import sys
import base64
import os
import logging

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from functools import partial
from network.network import ClientSocket
from network.package import *

logger = logging.getLogger(__name__)

jsonPack = JsonPackage()
bytePack = BytePackage()

class Book(QWidget):

    def __init__(self, bookInfo, parent):

        super(Book, self).__init__()

        self.parent = parent

        self.bookInfo = bookInfo
        self.initBook(bookInfo)
        self.path = os.path.join(self.parent.tempDir, self.id)

        self.layout = QHBoxLayout(self)

        # 设置阅读页面
        self.contentView = QtWidgets.QTextBrowser()

        relative_path_root = os.path.join(
            self.parent.tempDir, self.id)
        self.relative_paths = [self.parent.tempDir, relative_path_root]
        #for i in os.walk(relative_path_root):
        #    for j in i[2]:
        #        file_extension = os.path.splitext(j)[1]
        #        if file_extension == '.css':
        #            file_path = os.path.join(i[0], j)
        #            os.remove(file_path)
        #    relative_paths.append(os.path.join(relative_path_root, i[0]))
        self.contentView.setSearchPaths(self.relative_paths)
        self.createDir()


        # All content must be set through this function
        self.setContent()

        self.contentView.setFrameShape(QtWidgets.QFrame.NoFrame)
        self.contentView.setObjectName('contentView')

        self.layout.addWidget(self.contentView)

        if len(self.title) > 30:
            self.title = self.title[:30] + '...'
        idx = self.parent.tabWidget.addTab(self, self.title)
        self.parent.tabWidget.setCurrentIndex(idx)
        self.parent.opened[self.id] = self

    def initBook(self, bookInfo):
        self.id = bookInfo["id"]
        self.title = bookInfo["title"]
        self.authors = bookInfo["authors"]
        self.toc = bookInfo["toc"]
        #self.cover = bookInfo["cover"]

        self.tocModel = QStandardItemModel()
        self.tocModel.setHorizontalHeaderLabels(('目录',))
        self.generateTocModel()

        # 设置阅读位置
        self.current = 0

    def createDir(self):

        if os.path.exists(self.path):
            return 

        os.makedirs(os.path.join(self.path, "OEBPS/Images"))
        os.makedirs(os.path.join(self.path, "OEBPS/Text"))
        self.relative_paths.append(os.path.join(self.path, "OEBPS/Text"))
        self.contentView.setSearchPaths(self.relative_paths)

    def generateTocModel(self):
        # The toc list is:
        # 0: Level
        # 1: Title
        # 2: Chapter content / page number

        parent_list = []
        for i in self.toc:
            item = QtGui.QStandardItem()
            item.setText(i[1])
            item.setData(i[2], QtCore.Qt.UserRole)
            item.setData(i[1], QtCore.Qt.UserRole + 1)

            current_level = i[0]
            if current_level == 1:
                self.tocModel.appendRow(item)
                parent_list.clear()
                parent_list.append(item)
            else:
                parent_list[current_level - 2].appendRow(item)
                try:
                    next_level = self.toc[self.toc.index(i) + 1][0]
                    if next_level > current_level:
                        parent_list.append(item)

                    if next_level < current_level:
                        level_difference = current_level - next_level
                        parent_list = parent_list[:-level_difference]
                except IndexError:
                    pass

        # This is needed to be able to have the toc Combobox
        # jump to the correct position in the book when it is
        # first opened
        self.parent.bookToolBar.tocBox.setModel(self.tocModel)
        self.parent.bookToolBar.tocTreeView.expandAll()

#正文页面
    def createContentView(self):

        self.createChapters()
        self.createContent()
        self.createLastButton()
        self.createNextButton()

        self.layout.addWidget(self.browser, 0, 1, 1, 2)
        self.layout.setColumnStretch(0, 1)
        self.layout.setColumnStretch(1, 2)
        self.layout.setColumnStretch(2, 2)

    def setContent(self):

        if self.current == 0:
            self.parent.bookToolBar.lastChapter.setEnabled(False)
        else:
            self.parent.bookToolBar.lastChapter.setEnabled(True)

        if self.current == len(self.toc) - 1:
            self.parent.bookToolBar.nextChapter.setEnabled(False)
        else:
            self.parent.bookToolBar.nextChapter.setEnabled(True)

        requestDict = {
            "type": "content",
            "id": self.id,
            "chapter": self.current
            }
        jsonPack.setData(requestDict)
        recvPack = self.parent.client.send(jsonPack)
        content = recvPack.data["content"]
        res = recvPack.data["res"]
        logger.debug(f"setContent: {self.current}")
        logger.debug(res.keys())

        for path, data in res.items():

            data = base64.b64decode(data.encode())
            temppath = os.path.split(path)[0]
            #if temppath not in self.relative_paths:
            #    self.relative_paths.append(temppath)
            #    self.contentView.setSearchPaths(self.relative_paths)
            #temppath = os.path.join(self.path, temppath)
            #if not os.path.exists(temppath):
            #    os.makedirs(temppath)
            try:
                f = open(os.path.relpath(os.path.join(self.path, path)), mode = "wb")
                f.write(data)
                f.close()
            except:
                pass

        self.contentView.clear()
        self.contentView.setHtml(content)

        self.set_tocBox_index(self.current + 1, None)

    def set_tocBox_index(self, current_position=1, tocBox=None):

        position_reference = 1
        for i in reversed(self.toc):
            if i[2] <= current_position:
                position_reference = i[2]
                break

        # Match the position reference to the corresponding
        # index in the QTreeView / QCombobox
        try:
            matchingIndex = self.tocModel.match(
                self.tocModel.index(0, 0),
                QtCore.Qt.UserRole,
                position_reference,
                2, QtCore.Qt.MatchRecursive)[0]
        except IndexError:
            return

        # A tocBox name is specified for the context menu
        if not tocBox:
            tocBox = self.parent.bookToolBar.tocBox

        # The following sets the QCombobox index according
        # to the index found above.
        tocBox.blockSignals(True)
        currentRootModelIndex = tocBox.rootModelIndex()
        tocBox.setRootModelIndex(matchingIndex.parent())
        tocBox.setCurrentIndex(matchingIndex.row())
        tocBox.setRootModelIndex(currentRootModelIndex)
        tocBox.blockSignals(False)
